package com.zlcx.tz.live.service.impl;

import com.google.common.collect.Maps;
import com.google.common.collect.Lists;
import com.alibaba.fastjson.JSON;
import com.zlcx.tz.live.client.MessageClient;
import com.zlcx.tz.live.client.PushMessageClient;
import com.zlcx.tz.live.client.SocketClient;
import com.zlcx.tz.live.client.UserClient;
import com.zlcx.tz.live.client.vo.UserFriendVO;
import com.zlcx.tz.live.constant.MsgContentIdType;
import com.zlcx.tz.live.enums.MessageType;
import com.zlcx.tz.live.constant.RedisKeyConst;
import com.zlcx.tz.live.constant.ResultStatus;
import com.zlcx.tz.live.domain.LiveRoomInfo;
import com.zlcx.tz.live.enums.RoomMicStatus;
import com.zlcx.tz.live.enums.RoomState;
import com.zlcx.tz.live.exception.CheckRunException;
import com.zlcx.tz.live.utils.SignUtil;
import com.zlcx.tz.live.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import static com.zlcx.tz.live.enums.RoomState.HEART_MISS_CLOSED;

/**
 * <p>对接消息服务</p>
 * <PRE>
 * <BR>    修改记录
 * <BR>-----------------------------------------------
 * <BR>    修改日期         修改人          修改内容
 * </PRE>
 *
 * @author zl
 * @version 1.0
 * @date Created in 2019/4/18 20:10
 * @copyright: Copyright (c) founders
 */
@Slf4j
@Service
public class MessageService {


    @Autowired
    MessageClient messageClient;

    @Autowired
    PushMessageClient pushMessageClient;

    @Autowired
    UserClient userClient;

    @Value("${shangde.sign.secret}")
    String secret;

    @Resource(name = "msgExecutor")
    AsyncTaskExecutor asyncTaskExecutor;

    @Autowired
    SocketClient socketClient;

    @Autowired
    UserService userService;

    @Autowired
    RedisTemplate redisTemplate;

    private Logger traceLoger = LoggerFactory.getLogger("traceloger");

    /**
     * 发送短息通知
     *
     * @param phones
     * @param emsMsg
     */
    public void sendEmsMsg(String phones, String emsMsg, ArrayList<String> params) {

        asyncTaskExecutor.execute(() -> {
            ResultVO resultVO = null;
            Map<String, String[]> requestParams = new HashMap<>(2);
            requestParams.put("phones", new String[]{phones});
            requestParams.put("reportContent", new String[]{emsMsg});
            try {
                long t1 = System.currentTimeMillis();
                String sig = SignUtil.sign(secret, requestParams);
                resultVO = userClient.sendEmsMsg(phones, emsMsg, params);
                long t2 = System.currentTimeMillis();
                log.info("发送短信cost:{}ms，requestParams={},resultVO={}", t2 - t1, JSON.toJSONString(requestParams), JSON.toJSONString(resultVO));
                if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                    log.error("发送短信失败，cost:{}ms，requestParams={},resultVO={}", t2 - t1, JSON.toJSONString(requestParams), JSON.toJSONString(resultVO));
                    throw new CheckRunException("发送短信失败：phones=" + phones);
                }
            } catch (Exception e) {
                log.error("发送短信失败，requestParams={},resultVO={},e={}", JSON.toJSONString(requestParams), JSON.toJSONString(resultVO), e);
            }
        });
    }


    /**
     * 房主创建房间之后通知其道友
     *
     * @param roomInfo
     * @param hostUserId
     */
    public void createRoomMsg(LiveRoomInfo roomInfo, Long hostUserId) {

        asyncTaskExecutor.execute(() -> {
            List<UserFriendVO> friendVOList = userService.userFriendsList(hostUserId);
            if (CollectionUtils.isEmpty(friendVOList)) {
                log.info("房主{}没有道友！", hostUserId);
                return;
            }

            String message = "我正在连麦学习，快来一起加入～";
            String title = "快来和我一起连麦学习";
            String content = "我正在\"" + roomInfo.getRoomName() + "\"连麦学习，快来加入和我一起学～";
            Map<String, Object> extras = Maps.newHashMap();
            extras.put("roomId", roomInfo.getId());
            extras.put("roomAvatar", roomInfo.getRoomAvatar());
            extras.put("title", title);
            extras.put("content", content);

            ResultVO resultVO = null;
//            for (UserFriendVO friendVO : friendVOList) {
//                ShareMsgParamVO msgEntity = new ShareMsgParamVO();
//                msgEntity.setFromUserId(String.valueOf(hostUserId));
//                msgEntity.setToId(String.valueOf(friendVO.getFriendsUserId()));
//                msgEntity.setType(MsgType.PersonalDynamic.getCode());
//                msgEntity.setMessage(message);
//                msgEntity.setContentId(String.valueOf(roomInfo.getId()));
//                msgEntity.setContentType(MsgContentIdType.Room.getCode());
//                msgEntity.setExtras(extras);
//
//                if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
//                    msgEntity.setConnectType(MsgType.PersonalDynamic.getConnectType());
//                }
//
//                long t1 = System.currentTimeMillis();
//                try {
//                    traceLoger.info("createRoomMsg 创建房间通知道友 socket，房间【{}】房主【{}】道友【{}】消息类型【{}】内容类型【{}】", roomInfo.getId(), hostUserId, friendVO.getFriendsUserId(), msgEntity.getType(), msgEntity.getConnectType());
//                    resultVO = socketClient.sendMsg(msgEntity);
//                    long t2 = System.currentTimeMillis();
//                    traceLoger.info("createRoomMsg 创建房间通知道友 socket，房间【{}】房主【{}】道友【{}】消息类型【{}】内容类型【{}】cost:{}ms,resultVO={}", roomInfo.getId(), hostUserId, friendVO.getFriendsUserId(), msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
//                    log.info("房主创建房间通知道友cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
//                    if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
//                        log.error("房主创建房间通知道友失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
//                    }
//                } catch (Exception e) {
//                    log.error("房主创建房间通知道友失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
//                }
//            }

            MessageParamVO messageParamVO = new MessageParamVO();
            messageParamVO.setBusinessId(String.valueOf(roomInfo.getId()));
            messageParamVO.setContent(content);
            messageParamVO.setIsGroupSend(false);
            messageParamVO.setTitle(title);
            messageParamVO.setType(MessageType.DynamicCreateRoom.getCode());
            messageParamVO.setExcludeUserIds(Lists.newArrayList());
            messageParamVO.setUserIds(friendVOList.stream().map(UserFriendVO::getFriendsUserId).collect(Collectors.toList()));
            long t1 = System.currentTimeMillis();
            try {
                traceLoger.info("createRoomMsg 创建房间发送道友动态消息 message，房间【{}】房主【{}】道友【{}】消息类型【{}】", roomInfo.getId(), hostUserId, messageParamVO.getUserIds(), messageParamVO.getType());
                resultVO = messageClient.sendMsg(messageParamVO);
                long t2 = System.currentTimeMillis();
                traceLoger.info("createRoomMsg 创建房间发送道友动态消息 message，房间【{}】房主【{}】道友【{}】消息类型【{}】,cost:{}ms，resultVO={}", roomInfo.getId(), hostUserId, messageParamVO.getUserIds(), messageParamVO.getType(), t2 - t1, JSON.toJSONString(resultVO));
                log.info("房主创建房间发送道友动态消息cost:{}ms，messageParamVO={},resultVO={}", t2 - t1, JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
                if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                    log.error("房主创建房间发送道友动态消息失败cost:{}ms，messageParamVO={},resultVO={}", t2 - t1, JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
                }
            } catch (Exception e) {
                log.error("房主创建房间发送道友动态消息失败，messageParamVO={},resultVO={}", JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
            }


        });

    }

    /**
     * 申请上麦
     */
    public void applyPublishMsg(Long roomId, Long publisherRecordId, UserVO userInfo, Date applyTime) {

//        asyncTaskExecutor.execute(()->{

        String message = userInfo.getName() + " 申请上麦";
        Map<String, Object> extras = Maps.newHashMap();
        extras.put("publisherRecordId", publisherRecordId);
        extras.put("userId", userInfo.getId());
        extras.put("userName", userInfo.getName());
        extras.put("userAvatar", userInfo.getAvatarUrl());
        extras.put("applyTime", DateFormatUtils.format(applyTime, "yyyy-MM-dd HH:mm:ss"));
        extras.put("applyTimeShort", DateFormatUtils.format(applyTime, "HH:mm"));

        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
        msgEntity.setFromUserId(String.valueOf(userInfo.getId()));
        msgEntity.setToId(String.valueOf(roomId));
        msgEntity.setType(MessageType.ApplyPublish.getCode());
        msgEntity.setMessage(message);
        msgEntity.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            msgEntity.setConnectType(MessageType.ApplyPublish.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("applyPublishMsg 申请上麦消息 socket，房间【{}】用户【{}】申请记录【{}】消息类型【{}】内容类型【{}】", roomId, userInfo.getId(), publisherRecordId, msgEntity.getType(), msgEntity.getConnectType());
            resultVO = socketClient.sendMsg(msgEntity);
            long t2 = System.currentTimeMillis();
            traceLoger.info("applyPublishMsg 申请上麦消息 socket，房间【{}】用户【{}】申请记录【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomId, userInfo.getId(), publisherRecordId, msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("申请上麦消息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("申请上麦消息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("申请上麦消息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
        }

//        });


    }

    /**
     * 取消申请上麦消息
     *
     * @param roomId
     * @param userInfo
     */
    public void cancelApplyPublish(Long roomId, Long publisherRecordId, UserVO userInfo, Date applyTime) {

//        asyncTaskExecutor.execute(()->{

        String message = userInfo.getName() + " 已取消申请";
        Map<String, Object> extras = Maps.newHashMap();
        extras.put("publisherRecordId", publisherRecordId);
        extras.put("userId", userInfo.getId());
        extras.put("userName", userInfo.getName());
        extras.put("userAvatar", userInfo.getAvatarUrl());
        extras.put("applyTime", DateFormatUtils.format(applyTime, "yyyy-MM-dd HH:mm:ss"));
        extras.put("applyTimeShort", DateFormatUtils.format(applyTime, "HH:mm"));

        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
        msgEntity.setFromUserId(String.valueOf(userInfo.getId()));
        msgEntity.setToId(String.valueOf(roomId));
        msgEntity.setType(MessageType.CancelApplyPublish.getCode());
        msgEntity.setMessage(message);
        msgEntity.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            msgEntity.setConnectType(MessageType.CancelApplyPublish.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("cancelApplyPublish 取消申请上麦消息 socket，房间【{}】用户【{}】申请记录【{}】消息类型【{}】内容类型【{}】", roomId, userInfo.getId(), publisherRecordId, msgEntity.getType(), msgEntity.getConnectType());
            resultVO = socketClient.sendMsg(msgEntity);
            long t2 = System.currentTimeMillis();
            traceLoger.info("cancelApplyPublish 取消申请上麦消息 socket，房间【{}】用户【{}】申请记录【{}】消息类型【{}】内容类型【{}】,cost:{}ms,resultVO={}", roomId, userInfo.getId(), publisherRecordId, msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("取消申请上麦消息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("取消申请上麦消息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("取消申请上麦消息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
        }

//        });

    }

    /**
     * 房主同意上麦消息
     *
     * @param roomId
     * @param hostUserId
     * @param userInfo
     */
    public void agreeApplyPublish(Long roomId, Long publisherRecordId, Long hostUserId, UserVO userInfo) {

//        asyncTaskExecutor.execute(()->{

        String message = userInfo.getName() + " 已上麦";
        Map<String, Object> extras = Maps.newHashMap();
        extras.put("publisherRecordId", publisherRecordId);
        extras.put("userId", userInfo.getId());
        extras.put("userName", userInfo.getName());

        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
        msgEntity.setFromUserId(String.valueOf(hostUserId));
        msgEntity.setToId(String.valueOf(roomId));
        msgEntity.setType(MessageType.AgreeApplyPublish.getCode());
        msgEntity.setMessage(message);
        msgEntity.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            msgEntity.setConnectType(MessageType.AgreeApplyPublish.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("agreeApplyPublish 房主同意上麦消息 socket，房间【{}】房主【{}】同意用户【{}】上麦申请记录【{}】消息类型【{}】内容类型【{}】", roomId, hostUserId, userInfo.getId(), publisherRecordId, msgEntity.getType(), msgEntity.getConnectType());
            resultVO = socketClient.sendMsg(msgEntity);
            long t2 = System.currentTimeMillis();
            traceLoger.info("agreeApplyPublish 房主同意上麦消息 socket，房间【{}】房主【{}】同意用户【{}】上麦申请记录【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomId, hostUserId, userInfo.getId(), publisherRecordId, msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("房主同意上麦消息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("房主同意上麦消息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("房主同意上麦消息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
        }

//        });
    }

    /**
     * 下麦消息
     */
    public void quitPublish(Long roomId, UserVO userInfo) {
//        asyncTaskExecutor.execute(()->{

        String message = userInfo.getName() + " 已下麦";
        Map<String, Object> extras = Maps.newHashMap();
        extras.put("userId", userInfo.getId());
        extras.put("userName", userInfo.getName());

        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
        msgEntity.setFromUserId(String.valueOf(userInfo.getId()));
        msgEntity.setToId(String.valueOf(roomId));
        msgEntity.setType(MessageType.QuitPublish.getCode());
        msgEntity.setMessage(message);
        msgEntity.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            msgEntity.setConnectType(MessageType.QuitPublish.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("quitPublish 下麦消息 socket，房间【{}】用户【{}】消息类型【{}】内容类型【{}】", roomId, userInfo.getId(), msgEntity.getType(), msgEntity.getConnectType());
            resultVO = socketClient.sendMsg(msgEntity);
            long t2 = System.currentTimeMillis();
            traceLoger.info("quitPublish 下麦消息 socket，房间【{}】用户【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomId, userInfo.getId(), msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("下麦消息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("下麦消息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("下麦消息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
        }

//        });

    }

    /**
     * 切换房主消息
     *
     * @param roomId
     * @param oldHostUserId
     * @param hostUserInfo
     */
    public void hostChange(Long roomId, Long oldHostUserId, UserVO hostUserInfo) {

//        asyncTaskExecutor.execute(()->{

        String message = hostUserInfo.getName() + " 成为新房主";
        Map<String, Object> extras = Maps.newHashMap();
        extras.put("oldHostUserId", oldHostUserId);
        extras.put("hostUserId", hostUserInfo.getId());
        extras.put("userName", hostUserInfo.getName());
        extras.put("roomAvatar", hostUserInfo.getAvatarUrl());

        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
        msgEntity.setFromUserId(String.valueOf(oldHostUserId));
        msgEntity.setToId(String.valueOf(roomId));
        msgEntity.setType(MessageType.HostChange.getCode());
        msgEntity.setMessage(message);
        msgEntity.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            msgEntity.setConnectType(MessageType.HostChange.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("hostChange 切换房主消息 socket，房间【{}】老房主【{}】新房主【{}】消息类型【{}】内容类型【{}】", roomId, oldHostUserId, hostUserInfo.getId(), msgEntity.getType(), msgEntity.getConnectType());
            resultVO = socketClient.sendMsg(msgEntity);
            long t2 = System.currentTimeMillis();
            traceLoger.info("hostChange 切换房主消息 socket，房间【{}】老房主【{}】新房主【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomId, oldHostUserId, hostUserInfo.getId(), msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("切换房主消息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("切换房主消息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("切换房主消息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
        }

//        });

    }


    /**
     * 全员禁麦操作消息
     *
     * @param roomId
     * @param micState
     * @param hostUserInfo
     */
    public void operateAllMic(Long roomId, Integer micState, UserVO hostUserInfo) {

//        asyncTaskExecutor.execute(()->{

        String message = hostUserInfo.getName() + " 开启了全员禁麦";
        if (RoomMicStatus.MIC_ON.getCode() == micState) {
            message = hostUserInfo.getName() + " 解除了全员禁麦";
        }

        Map<String, Object> extras = Maps.newHashMap();
        extras.put("micState", micState);
        extras.put("userId", hostUserInfo.getId());
        extras.put("userName", hostUserInfo.getName());

        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
        msgEntity.setFromUserId(String.valueOf(hostUserInfo.getId()));
        msgEntity.setToId(String.valueOf(roomId));
        msgEntity.setType(MessageType.OperateAllMic.getCode());
        msgEntity.setMessage(message);
        msgEntity.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            msgEntity.setConnectType(MessageType.OperateAllMic.getConnectType());
        }
        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("operateAllMic 全员禁麦操作消息 socket，房间【{}】房主【{}】麦克状态【{}】消息类型【{}】内容类型【{}】", roomId, hostUserInfo.getId(), micState, msgEntity.getType(), msgEntity.getConnectType());
            resultVO = socketClient.sendMsg(msgEntity);
            long t2 = System.currentTimeMillis();
            traceLoger.info("operateAllMic 全员禁麦操作消息 socket，房间【{}】房主【{}】麦克状态【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomId, hostUserInfo.getId(), micState, msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("全员禁麦操作消息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("全员禁麦操作消息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("全员禁麦操作消息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
        }

//        });

    }

    /**
     * 自己麦克操作消息
     *
     * @param roomId
     * @param micState
     * @param userInfo
     */
    public void operateSelfMic(Long roomId, Integer micState, UserVO userInfo) {

//        asyncTaskExecutor.execute(()->{

        String message = userInfo.getName() + " 关闭了麦克";
        if (RoomMicStatus.MIC_ON.getCode() == micState) {
            message = userInfo.getName() + " 开启了麦克";
        }

        Map<String, Object> extras = Maps.newHashMap();
        extras.put("micState", micState);
        extras.put("userId", userInfo.getId());
        extras.put("userName", userInfo.getName());

        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
        msgEntity.setFromUserId(String.valueOf(userInfo.getId()));
        msgEntity.setToId(String.valueOf(roomId));
        msgEntity.setType(MessageType.OperateSelfMic.getCode());
        msgEntity.setMessage(message);
        msgEntity.setExtras(extras);

        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            msgEntity.setConnectType(MessageType.OperateSelfMic.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("operateSelfMic 自己麦克操作消息 socket，房间【{}】用户【{}】麦克状态【{}】消息类型【{}】内容类型【{}】", roomId, userInfo.getId(), micState, msgEntity.getType(), msgEntity.getConnectType());
            resultVO = socketClient.sendMsg(msgEntity);
            long t2 = System.currentTimeMillis();
            traceLoger.info("operateSelfMic 自己麦克操作消息 socket，房间【{}】用户【{}】麦克状态【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomId, userInfo.getId(), micState, msgEntity.getType(), msgEntity.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("自己麦克操作消息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("自己麦克操作消息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("自己麦克操作消息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
        }

//        });


    }

    public void joinRoom(UserVO userVO, LiveRoomInfo roomInfo, boolean isVisitor) {
//        asyncTaskExecutor.execute(()->{
        ShareMsgParamVO shareMsgParamVO = new ShareMsgParamVO();
        String message = userVO.getName() + "加入了房间";
        Map<String, Object> extras = Maps.newHashMap();
        extras.put("userId", userVO.getId());
        extras.put("type", userVO.getType());
        extras.put("userName", userVO.getName());
        extras.put("userAvatar", userVO.getAvatarUrl());
        shareMsgParamVO.setFromUserId(String.valueOf(userVO.getId()));
        shareMsgParamVO.setToId(String.valueOf(roomInfo.getId()));
        shareMsgParamVO.setType(MessageType.JoinRoom.getCode());
        shareMsgParamVO.setMessage(message);
        shareMsgParamVO.setExtras(extras);

        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            shareMsgParamVO.setConnectType(MessageType.JoinRoom.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("joinRoom 用户进入房间通知 socket，房间【{}】用户【{}】消息类型【{}】内容类型【{}】", roomInfo.getId(), userVO.getId(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType());
            resultVO = socketClient.sendMsg(shareMsgParamVO);
            long t2 = System.currentTimeMillis();
            traceLoger.info("joinRoom 用户进入房间通知 socket，房间【{}】用户【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomInfo.getId(), userVO.getId(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("用户进入房间通知cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("用户进入房间通知失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("用户进入房间通知失败，msgEntity={},resultVO={}", JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
        }
//        });

    }

    public void exitRoom(UserVO userVO, LiveRoomInfo roomInfo, boolean isVisitor) {
//        asyncTaskExecutor.execute(()->{
        ShareMsgParamVO shareMsgParamVO = new ShareMsgParamVO();
        String message = userVO.getName() + "离开了房间";
        Map<String, Object> extras = Maps.newHashMap();
        extras.put("userId", userVO.getId());
        extras.put("userName", userVO.getName());
        extras.put("userAvatar", userVO.getAvatarUrl());

        shareMsgParamVO.setFromUserId(String.valueOf(userVO.getId()));
        shareMsgParamVO.setToId(String.valueOf(roomInfo.getId()));
        shareMsgParamVO.setType(MessageType.LeaveRoom.getCode());
        shareMsgParamVO.setMessage(message);
        shareMsgParamVO.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            shareMsgParamVO.setConnectType(MessageType.LeaveRoom.getConnectType());
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("exitRoom 用户离开房间通知 socket，房间【{}】用户【{}】消息类型【{}】内容类型【{}】", roomInfo.getId(), userVO.getId(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType());
            resultVO = socketClient.sendMsg(shareMsgParamVO);
            long t2 = System.currentTimeMillis();
            traceLoger.info("exitRoom 用户离开房间通知 socket，房间【{}】用户【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomInfo.getId(), userVO.getId(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("用户离开房间通知cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("用户离开房间通知失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("用户离开房间通知失败，msgEntity={},resultVO={}", JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
        }
//        });
    }

//    public void notNonalExit(UserVO userVO, LiveRoomInfo roomInfo) {
////        asyncTaskExecutor.execute(()->{
//
//        String content = "你上次的连麦学习异常中断!";
//        MessageParamVO messageParamVO = new MessageParamVO();
//        messageParamVO.setBusinessId(String.valueOf(userVO.getId()));
//        messageParamVO.setContent(content);
//        messageParamVO.setIsGroupSend(false);
//        messageParamVO.setType(MsgType.PersonalDynamic.getCode());
//        messageParamVO.setUserIds(Lists.newArrayList(userVO.getId()));
//        ResultVO resultVO = null;
//        long t1 = System.currentTimeMillis();
//        try {
//            traceLoger.info("notNonalExit 异常中断发送动态消息 message，房间【{}】用户【{}】消息类型【{}】", roomInfo.getId(), userVO.getId(), messageParamVO.getType());
//            resultVO = messageClient.sendMsg(messageParamVO);
//            long t2 = System.currentTimeMillis();
//            traceLoger.info("notNonalExit 异常中断发送动态消息 message，房间【{}】用户【{}】消息类型【{}】,cost:{}ms，resultVO={}", roomInfo.getId(), userVO.getId(), messageParamVO.getType(), t2 - t1, JSON.toJSONString(resultVO));
//            log.info("异常中断发送动态消息cost:{}ms，messageParamVO={},resultVO={}", t2 - t1, JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
//            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
//                log.error("异常中断发送动态消息失败cost:{}ms，messageParamVO={},resultVO={}", t2 - t1, JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
//            }
//        } catch (Exception e) {
//            log.error("异常中断发送动态消息失败，messageParamVO={},resultVO={}", JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
//        }
////        });
//    }

    public void closeRoom(LiveRoomInfo roomInfo, Long userId, Integer closeState) {
        log.debug("closeRoomMsg roomInfo={},hostUserId={}", JSON.toJSONString(roomInfo), userId);
//        asyncTaskExecutor.execute(()->{
        ShareMsgParamVO shareMsgParamVO = new ShareMsgParamVO();
        String message = "房主关闭房间，请切换到其他房间";

        shareMsgParamVO.setToId(String.valueOf(roomInfo.getId()));
        if (RoomState.BE_CLOSED.getCode() == closeState) {
            message = "管理员强制关闭房间，请切换到其他房间";
            log.debug(message);
            shareMsgParamVO.setType(MessageType.AdminCloseRoom.getCode());
            if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
                shareMsgParamVO.setConnectType(MessageType.AdminCloseRoom.getConnectType());
            }
            //为自动关闭房间而添加
        } else if (RoomState.SYS_CLOSED.getCode() == closeState) {
            message = "下课时间到，休息一会再继续学习吧";
            log.debug(message);
            shareMsgParamVO.setType(MessageType.AdminCloseRoom.getCode());
            if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
                shareMsgParamVO.setConnectType(MessageType.AdminCloseRoom.getConnectType());
            }
        } else if (HEART_MISS_CLOSED.getCode() == closeState) {
            message = "心跳丢失强制关闭房间";
            log.debug(message);
            shareMsgParamVO.setType(MessageType.HeartMissCloseRoom.getCode());
            if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
                shareMsgParamVO.setConnectType(MessageType.HeartMissCloseRoom.getConnectType());
            }
        }else {
            shareMsgParamVO.setType(MessageType.CloseRoom.getCode());
            if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
                shareMsgParamVO.setConnectType(MessageType.CloseRoom.getConnectType());
            }
        }

        shareMsgParamVO.setMessage(message);
        shareMsgParamVO.setFromUserId(String.valueOf(userId));

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("closeRoom 关闭房间通知 socket，房间【{}】用户【{}】关闭类型【{}】消息类型【{}】内容类型【{}】", roomInfo.getId(), userId, RoomState.getRoomState(closeState).getTips(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType());
            resultVO = socketClient.sendMsg(shareMsgParamVO);
            long t2 = System.currentTimeMillis();
            traceLoger.info("closeRoom 关闭房间通知 socket，房间【{}】用户【{}】关闭类型【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomInfo.getId(), userId, RoomState.getRoomState(closeState).getTips(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("关闭房间通知cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("关闭房间通知失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("关闭房间通知失败，msgEntity={},resultVO={}", JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            log.error("", e);
        }

        List<UserFriendVO> friendVOList = userService.userFriendsList(userId);
        if (CollectionUtils.isEmpty(friendVOList)) {
            log.info("房主{}没有道友！", userId);
            return;
        }


        String title = "房间关闭";
        String content = "\"" + roomInfo.getRoomName() + "\"关闭～";
        MessageParamVO messageParamVO = new MessageParamVO();
        messageParamVO.setBusinessId(String.valueOf(roomInfo.getId()));
        messageParamVO.setContent(content);
        messageParamVO.setIsGroupSend(false);
        messageParamVO.setTitle(title);
        messageParamVO.setType(MessageType.DynamicCloseRoom.getCode());
        messageParamVO.setExcludeUserIds(Lists.newArrayList());
        messageParamVO.setUserIds(friendVOList.stream().map(UserFriendVO::getFriendsUserId).collect(Collectors.toList()));
        t1 = System.currentTimeMillis();
        try {
            traceLoger.info("closeRoom 关闭房间发送道友动态消息 message，房间【{}】用户【{}】关闭类型【{}】通知用户【{}】消息类型【{}】内容类型【{}】", roomInfo.getId(), userId, RoomState.getRoomState(closeState).getTips(), messageParamVO.getUserIds(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType());
            resultVO = messageClient.sendMsg(messageParamVO);
            long t2 = System.currentTimeMillis();
            traceLoger.info("closeRoom 关闭房间发送道友动态消息 message，房间【{}】用户【{}】关闭类型【{}】通知用户【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomInfo.getId(), userId, RoomState.getRoomState(closeState).getTips(), messageParamVO.getUserIds(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("关闭房间发送道友动态消息cost:{}ms，messageParamVO={},resultVO={}", t2 - t1, JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("关闭房间发送道友动态消息失败cost:{}ms，messageParamVO={},resultVO={}", t2 - t1, JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("关闭房间发送道友动态消息失败，messageParamVO={},resultVO={}", JSON.toJSONString(messageParamVO), JSON.toJSONString(resultVO));
        }


//        });
    }

    public void kicking(Long roomOwnerUserId, UserVO userVO, LiveRoomInfo roomInfo, String role) {
//        asyncTaskExecutor.execute(()->{
        ShareMsgParamVO shareMsgParamVO = new ShareMsgParamVO();
        String message = "你被房主踢出了房间";

        Map<String, Object> extras = Maps.newHashMap();
        extras.put("userId", userVO.getId());
        extras.put("userName", userVO.getName());
        extras.put("userAvatar", userVO.getAvatarUrl());

        shareMsgParamVO.setFromUserId(String.valueOf(roomOwnerUserId));
        shareMsgParamVO.setToId(String.valueOf(roomInfo.getId()));
        shareMsgParamVO.setType(MessageType.KickingUser.getCode());
        shareMsgParamVO.setMessage(message);
        shareMsgParamVO.setContentId(String.valueOf(userVO.getId()));
        shareMsgParamVO.setContentType(MsgContentIdType.Person.getCode());
        shareMsgParamVO.setExtras(extras);
        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
            shareMsgParamVO.setConnectType(MessageType.KickingUser.getConnectType());
        }
        if (StringUtils.isNotEmpty(role) && "system".equals(role)) {
            shareMsgParamVO.setType(MessageType.SystemKickingUser.getCode());
            shareMsgParamVO.setMessage("你被系统踢出了房间");
            if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
                shareMsgParamVO.setConnectType(MessageType.SystemKickingUser.getConnectType());
            }
        }

        ResultVO resultVO = null;
        long t1 = System.currentTimeMillis();
        try {
            traceLoger.info("kicking 用户踢出房间通知 socket，房间【{}】房主【{}】用户【{}】消息类型【{}】内容类型【{}】", roomInfo.getId(), roomOwnerUserId, userVO.getId(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType());
            resultVO = socketClient.sendMsg(shareMsgParamVO);
            long t2 = System.currentTimeMillis();
            traceLoger.info("kicking 用户踢出房间通知 socket，房间【{}】房主【{}】用户【{}】消息类型【{}】内容类型【{}】,cost:{}ms，resultVO={}", roomInfo.getId(), roomOwnerUserId, userVO.getId(), shareMsgParamVO.getType(), shareMsgParamVO.getConnectType(), t2 - t1, JSON.toJSONString(resultVO));
            log.info("用户踢出房间通知cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                log.error("用户踢出房间通知失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
            }
        } catch (Exception e) {
            log.error("用户踢出房间通知失败，msgEntity={},resultVO={}", JSON.toJSONString(shareMsgParamVO), JSON.toJSONString(resultVO));
        }
//        });
    }


    /**
     * 邀请道友和群友上麦
     *
     * @param roomId
     * @param userId
     * @param shareToUserIds
     * @param shareToGroupIds
     * @param roomInfo
     */
    public void invitePublish(Long roomId, Long userId, List<Long> shareToUserIds, List<String> shareToGroupIds, LiveRoomInfo roomInfo) {
        asyncTaskExecutor.execute(() -> {
            ResultVO resultVO = null;
            try {

                String message = "我正在连麦学习，快来一起加入～";
                String title = "快来和我一起连麦学习";
                String content = "我正在\"" + roomInfo.getRoomName() + "\"连麦学习，快来加入和我一起学～";
                Map<String, Object> extras = Maps.newHashMap();
                extras.put("roomId", roomInfo.getId());
                extras.put("roomAvatar", roomInfo.getRoomAvatar());
                extras.put("title", title);
                extras.put("content", content);

                UserVO userInfo = userService.getUserInfo(userId);
                extras.put("fromAvatar", userInfo.getAvatarUrl());
                extras.put("fromName", userInfo.getName());

                if (CollectionUtils.isNotEmpty(shareToUserIds)) {
                    for (Long toUid : shareToUserIds) {

                        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
                        msgEntity.setFromUserId(String.valueOf(userId));
                        msgEntity.setToId(String.valueOf(toUid));
                        msgEntity.setType(MessageType.ShareRoomToPerson.getCode());
                        msgEntity.setMessage(message);
                        msgEntity.setContentId(String.valueOf(roomInfo.getId()));
                        msgEntity.setContentType(MsgContentIdType.Room.getCode());
                        msgEntity.setExtras(extras);
                        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
                            msgEntity.setConnectType(MessageType.ShareRoomToPerson.getConnectType());
                        }
                        long t1 = System.currentTimeMillis();
                        try {
                            resultVO = socketClient.sendMsg(msgEntity);
                            long t2 = System.currentTimeMillis();
                            log.info("发送个人邀请信息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
                            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                                log.error("发送个人邀请信息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
                            }
                        } catch (Exception e) {
                            log.error("发送个人邀请信息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
                        }
                    }

                }

                if (CollectionUtils.isNotEmpty(shareToGroupIds)) {
                    for (String toGroupId : shareToGroupIds) {

                        ShareMsgParamVO msgEntity = new ShareMsgParamVO();
                        msgEntity.setFromUserId(String.valueOf(userId));
                        msgEntity.setToId(toGroupId);
                        msgEntity.setType(MessageType.ShareRoomToGroup.getCode());
                        msgEntity.setMessage(content);
                        msgEntity.setContentId(String.valueOf(roomInfo.getId()));
                        msgEntity.setContentType(MsgContentIdType.Room.getCode());
                        msgEntity.setExtras(extras);
                        if (redisTemplate.opsForValue().get(RedisKeyConst.getSocketSwitchKey()) == null) {
                            msgEntity.setConnectType(MessageType.ShareRoomToGroup.getConnectType());
                        }
                        long t1 = System.currentTimeMillis();
                        try {
                            resultVO = socketClient.sendMsg(msgEntity);
                            long t2 = System.currentTimeMillis();
                            log.info("发送群组邀请信息cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
                            if (resultVO == null || resultVO.getCode() == null || ResultStatus.SUCCESS.getCode() != resultVO.getCode()) {
                                log.error("发送群组邀请信息失败cost:{}ms，msgEntity={},resultVO={}", t2 - t1, JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
                            }
                        } catch (Exception e) {
                            log.error("发送群组邀请信息失败，msgEntity={},resultVO={}", JSON.toJSONString(msgEntity), JSON.toJSONString(resultVO));
                        }
                    }

                }

            } catch (Exception e) {
                log.error("发送邀请信息失败，roomId={},userId={},shareToUserIds={},shareToGroupIds={},resultVO={}", roomId, userId, shareToUserIds, shareToGroupIds, JSON.toJSONString(resultVO));
            }
        });

    }


}
